﻿namespace YnabCsvConverter
{
   using System;
   using System.Collections.Generic;
   using System.Diagnostics;
   using System.IO;
   using System.Reflection;
   using System.Windows;
   using System.Windows.Input;
   using System.Windows.Navigation;
   using Microsoft.Win32;
   using Properties;
   using Core;
   using Core.Converters;

   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
      /// <summary>
      /// Initializes a new instance of the <see cref="MainWindow" /> class.
      /// </summary>
      public MainWindow()
      {
         InitializeComponent();
         Loaded += HandleMainWindowLoaded;
         Unloaded += HanldeMainWindowUnloaded;

         DataContext = this;

         var scanner = new ConverterScanner();

         Converters = scanner.ScanAssemblyForConverters();

         _cbConverters.SelectedIndex = 0;
      }

      /// <summary>
      /// Gets or sets the converters.
      /// </summary>
      /// <value>
      /// The converters.
      /// </value>
      public List<ConverterItem> Converters { get; set; }

      /// <summary>
      /// Hanldes the main window unloaded.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HanldeMainWindowUnloaded(object sender, RoutedEventArgs e)
      {
      }

      /// <summary>
      /// Handles the main window loaded.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      void HandleMainWindowLoaded(object sender, RoutedEventArgs e)
      {
         _tbSource.Text = Settings.Default.SourceCsvPath;
         _tbTarget.Text = Settings.Default.TargetCsvPath;

         var version = Assembly.GetExecutingAssembly().GetName().Version;
         appVersion.Text = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Revision);
      }

      /// <summary>
      /// Handles the close click.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HandleCloseClick(object sender, RoutedEventArgs e)
      {
         Application.Current.Shutdown();
      }

      /// <summary>
      /// Handles the convert click.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HandleConvertClick(object sender, RoutedEventArgs e)
      {
         if (File.Exists(_tbTarget.Text))
         {
            var overwritePrompt = new OverwriteOrDeltaPrompt();
            var result = overwritePrompt.ShowDialog();

            if (result.HasValue && result.Value)
            {
               Convert(overwritePrompt.CreationMode);
            }
         }
         else
         {
            Convert(CreationMode.All);
         }
      }

      /// <summary>
      /// Converts the specified mode.
      /// </summary>
      /// <param name="mode">The mode.</param>
      private void Convert(CreationMode mode)
      {
         var result = new ConverterResult();
         try
         {
            var converterItem = _cbConverters.SelectedItem as ConverterItem;

            if (converterItem != null)
            {
               result = converterItem.Converter.Convert(_tbSource.Text, _tbTarget.Text, mode);
            }
         }
         catch (Exception ex)
         {
            result.IsSuccess = false;

            var errorWindow = new ErrorWindow("Could not convert.\r\n" + ex.Message);
            errorWindow.ShowDialog();
         }

         if (result.IsSuccess)
         {
            var convertReportWindow = new ConvertReportWindow();
            convertReportWindow.ShowDialog();
         }
      }

      /// <summary>
      /// Handles the select source CSV file.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HandleSelectSourceCsvFile(object sender, RoutedEventArgs e)
      {
         var dialog = new OpenFileDialog();

         dialog.CheckFileExists = true;
         dialog.Filter = "(csv)|*.csv";

         if (File.Exists(_tbSource.Text))
         {
            dialog.InitialDirectory = new FileInfo(_tbSource.Text).DirectoryName;
         }

         var result = dialog.ShowDialog();

         if (result.Value)
         {
            _tbSource.Text = dialog.FileName;
         }

         _tbTarget.Text = dialog.FileName.Replace(".csv", ".ynab.csv");
      }

      /// <summary>
      /// Handles the select target CSV file.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HandleSelectTargetCsvFile(object sender, RoutedEventArgs e)
      {
         var dialog = new SaveFileDialog();
         dialog.Filter = "(csv)|*.csv";
         dialog.CheckPathExists = false;
         dialog.OverwritePrompt = false;

         var result = dialog.ShowDialog();

         if (result.Value)
         {
            _tbTarget.Text = dialog.FileName;
         }
      }

      /// <summary>
      /// Handles the window mouse down.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="MouseButtonEventArgs" /> instance containing the event data.</param>
      private void HandleWindowMouseDown(object sender, MouseButtonEventArgs e)
      {
         DragMove();
      }

      /// <summary>
      /// Saves the source target paths.
      /// </summary>
      private void SaveSourceTargetPaths()
      {
         try
         {
            Settings.Default.SourceCsvPath = _tbSource.Text;
            Settings.Default.TargetCsvPath = _tbTarget.Text;
            Settings.Default.Save();
         }
         // ReSharper disable EmptyGeneralCatchClause
         catch
         // ReSharper restore EmptyGeneralCatchClause
         {
            // Ignore all errors, don't care if this feature works or not, because
            // it is of minor usage.
         }
      }

      /// <summary>
      /// Handles the hyperlink request navigate.
      /// </summary>
      /// <param name="sender">The sender.</param>
      /// <param name="e">The <see cref="RequestNavigateEventArgs" /> instance containing the event data.</param>
      /// <exception cref="System.NotImplementedException"></exception>
      private void HandleHyperlinkRequestNavigate(object sender, RequestNavigateEventArgs e)
      {
         Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
         e.Handled = true;
      }
   }
}
